home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR10 / TGE129C.ZIP / SOURCE / CLIP.C < prev    next >
C/C++ Source or Header  |  1993-08-20  |  4KB  |  151 lines

  1. /*****************************************************************************
  2. *       The Graphics Engine version 1.29ßC                                   *
  3. *                                                                            *
  4. *       The Graphics Engine code and documentation are Copyright (c) 1993    *
  5. *       by Matthew Hildebrand.                                               *
  6. *                                                                            *
  7. *       Unauthorised usage or modification of any or all of The Graphics     *
  8. *       Engine is strictly prohibited.                                       *
  9. *****************************************************************************/
  10.  
  11. #include "tge.h"
  12.  
  13.  
  14. /****
  15. ***** Initial data declarations
  16. ****/
  17.  
  18. #define X1    (*x1)
  19. #define Y1    (*y1)
  20. #define X2    (*x2)
  21. #define Y2    (*y2)
  22.  
  23. struct endpoints
  24. {
  25.   int x1, y1, x2, y2;
  26. };
  27.  
  28. union outCodes
  29. {
  30.   struct
  31.   {
  32.     unsigned code0 : 1;        /* x<VIEWPORTULX */
  33.     unsigned code1 : 1;        /* y<VIEWPORTULY */
  34.     unsigned code2 : 1;        /* x>VIEWPORTLRX */
  35.     unsigned code3 : 1;        /* y>VIEWPORTLRY */
  36.   } ocs;
  37.   int outcodes;
  38. };
  39.  
  40. static void setOutCodes(union outCodes *ocu, int x, int y);
  41.  
  42.  
  43. /****
  44. ***** Clip a line
  45. ****/
  46.  
  47. int TGE_clipLine(int *x1, int *y1, int *x2, int *y2)
  48. {
  49.   union outCodes ocu1, ocu2;
  50.   int inside, outside;
  51.   int temp;
  52.  
  53.   /* initialize 4-bit codes */
  54.   setOutCodes(&ocu1, X1, Y1);
  55.   setOutCodes(&ocu2, X2, Y2);
  56.  
  57.   inside = ((ocu1.outcodes | ocu2.outcodes) == 0);
  58.   outside = ((ocu1.outcodes & ocu2.outcodes) != 0);
  59.  
  60.   while (!outside && !inside)
  61.   {
  62.     if (ocu1.outcodes == 0)        // swap endpoints if necessary so
  63.     {                    // that (x1,y1) needs to be clipped
  64.       temp = X1;        /* swap X1 and X2 */
  65.       X1 = X2;
  66.       X2 = temp;
  67.       temp = Y1;        /* swap Y1 and Y2 */
  68.       Y1 = Y2;
  69.       Y2 = temp;
  70.       temp = ocu1.outcodes;    /* swap ocu1 and ocu2 */
  71.       ocu1 = ocu2;
  72.       ocu2.outcodes = temp;
  73.     }
  74.  
  75.     if (ocu1.ocs.code0)            /* clip left */
  76.     {
  77.       Y1 += (int)((long)(Y2-Y1)*(VIEWPORTULX-X1)/(X2-X1));
  78.       X1 = VIEWPORTULX;
  79.     }
  80.     else if (ocu1.ocs.code1)        /* clip above */
  81.     {
  82.       X1 += (int)((long)(X2-X1)*(VIEWPORTULY-Y1)/(Y2-Y1));
  83.       Y1 = VIEWPORTULY;
  84.     }
  85.     else if (ocu1.ocs.code2)        /* clip right */
  86.     {
  87.       Y1 += (int)((long)(Y2-Y1)*(VIEWPORTLRX-X1)/(X2-X1));
  88.       X1 = VIEWPORTLRX;
  89.     }
  90.     else if (ocu1.ocs.code3)        /* clip below */
  91.     {
  92.       X1 += (int)((long)(X2-X1)*(VIEWPORTLRY-Y1)/(Y2-Y1));
  93.       Y1 = VIEWPORTLRY;
  94.     }
  95.  
  96.     setOutCodes(&ocu1, X1, Y1);
  97.  
  98.     inside = ((ocu1.outcodes | ocu2.outcodes) == 0);    /* update codes */
  99.     outside = ((ocu1.outcodes & ocu2.outcodes) != 0);
  100.   }
  101.  
  102.   return (inside);
  103. }
  104.  
  105. void setOutCodes(union outCodes *u, int x, int y)
  106. {
  107.   u->outcodes = 0;
  108.   u->ocs.code0 = (x < VIEWPORTULX);
  109.   u->ocs.code1 = (y < VIEWPORTULY);
  110.   u->ocs.code2 = (x > VIEWPORTLRX);
  111.   u->ocs.code3 = (y > VIEWPORTLRY);
  112. }
  113.  
  114.  
  115. /****
  116. ***** Clip a filled rectangle
  117. ****/
  118.  
  119. int TGE_clipFilledRect(int *ulx, int *uly, int *lrx, int *lry)
  120. {
  121.   int temp;
  122.  
  123.   if (*ulx > *lrx)            /* swap coords if necessary */
  124.   {
  125.     temp = *ulx;
  126.     *ulx = *lrx;
  127.     *lrx = temp;
  128.   }
  129.   if (*uly > *lry)
  130.   {
  131.     temp = *uly;
  132.     *uly = *lry;
  133.     *lry = temp;
  134.   }
  135.  
  136.   if (*ulx<=VIEWPORTLRX && *uly<=VIEWPORTLRY && *lrx>=VIEWPORTULX &&
  137.       *lry>=VIEWPORTULY)
  138.   {
  139.     if (*ulx < VIEWPORTULX)    /* clip to viewport boundaries */
  140.       *ulx = VIEWPORTULX;
  141.     if (*uly < VIEWPORTULY)
  142.       *uly = VIEWPORTULY;
  143.     if (*lrx > VIEWPORTLRX)
  144.       *lrx = VIEWPORTLRX;
  145.     if (*lry > VIEWPORTLRY)
  146.       *lry = VIEWPORTLRY;
  147.     return (1);            /* at least partially within viewport */
  148.   }
  149.   else
  150.     return (0);            /* entirely outside viewport */
  151. }